﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Microsoft.Win32;
using System.Threading;

namespace Documentanalysis
{
    public delegate void SendMessage();
    public partial class Task : Form
    {
        public List<string> folderArray;
        public string pathMask = "";
        public string fileMask = "";
        public SendMessage sendMessageToWaitingForm;
        public Document doc = new Document();
        public Waiting waiting;
        public bool needOpen = true;
        public Task()
        {
            InitializeComponent();
        }

        private void Task_Shown(object sender, EventArgs e)
        {
            Thread t2 = new Thread(new ParameterizedThreadStart(doTask));
            t2.IsBackground = true;
            t2.Start("");

            waiting = new Waiting();
            sendMessageToWaitingForm += waiting.getMessageFromTask;
            waiting.t2 = t2;
            //waiting.path = folderName;
            if (needOpen)
            {
                waiting.ShowDialog();
            }
        }

        private void doTask(object data)
        {
            doc.name = "全部";
            doc.sons = new List<Document>();

            for (int i = 0; i < folderArray.Count; i ++)
            {
                Document son = new Document();
                scanFolder(new DirectoryInfo(folderArray[i]), son);
                doc.sons.Add(son);
                doc.totalFolderCount += son.totalFolderCount;
                doc.totalFileCount += son.totalFileCount;
                doc.totalTypes = MergeDictionary(doc.totalTypes, son.totalTypes);
            }
            

            TreeNode tn = new TreeNode();
            addNode(tn, doc);

            treeView1.BeginInvoke(new MethodInvoker(() =>
            {
                treeView1.BeginUpdate();
            
                treeView1.Nodes.Add(tn);

                treeView1.SelectedNode = treeView1.Nodes[0];

                treeView1.EndUpdate();
            }));

            needOpen = false;
            if (sendMessageToWaitingForm != null)
            {
                sendMessageToWaitingForm();
            }


            writeLog();

        }

        private void writeLog()
        {
            string time = DateTime.Now.ToString("yyyyMMddhhmmssfff");
            StreamWriter sw = new StreamWriter(System.Windows.Forms.Application.StartupPath + "\\log\\" + time + ".txt");
            string t = "";
            foreach (var item in folderArray)
            {
                if (t.Equals(""))
                {
                    t = "{\"fullPath\": \"" + item + "\"}";
                }
                else
                {
                    t += ", " + "{\"fullPath\": \"" + item + "\"}";
                }
            }
            string s = "{\"path\": [" + t + "], \"doc\": " + doc.ToString() + "}";
            sw.Write(s);
            sw.Close();
        }
        private void scanFolder(DirectoryInfo root, Document doc)
        {
            try
            {
                doc.name = root.Name;
                doc.sons = new List<Document>();
                doc.dir = root;

                FileInfo[] files = fileMask.Equals("") ? root.GetFiles() : root.GetFiles().Where(f => f.Name.IndexOf(fileMask) < 0).ToArray();
                DirectoryInfo[] dirs = pathMask.Equals("") ? root.GetDirectories().Where(d => IsSystemHidden(d) == false).OrderBy(o => o.Name).ToArray() : root.GetDirectories().Where(d => IsSystemHidden(d) == false && d.Name.IndexOf(pathMask) < 0).OrderBy(o => o.Name).ToArray();
                
                doc.currentFolderCount = dirs.Length;
                doc.currentFileCount = files.Length;
                doc.totalFolderCount = dirs.Length;
                doc.totalFileCount = files.Length;

                var xxx = files.GroupBy(x => x.Extension.ToLower());
                foreach (var group in xxx)
                {
                    doc.currentTypes.Add(group.Key, group.Count());
                    doc.totalTypes.Add(group.Key, group.Count());
                }
     
                foreach (DirectoryInfo dir in dirs)
                {
                    Document son = new Document();
                    scanFolder(dir, son);
                    doc.totalFolderCount += son.totalFolderCount;
                    doc.totalFileCount += son.totalFileCount;
                    doc.totalTypes = MergeDictionary(doc.totalTypes, son.totalTypes);
                    doc.sons.Add(son);
                }
            }
            catch (Exception) {

            }
            
        }

        private void addNode(TreeNode node, Document doc)
        {
            node.Text = doc.name;
            node.ImageIndex = 0;
            node.Tag = doc;
            foreach (Document son in doc.sons)
            {
                TreeNode tn = new TreeNode();
                addNode(tn, son);
                node.Nodes.Add(tn);
            }
        }

        private static bool IsSystemHidden(DirectoryInfo dirInfo)
        {
            if (dirInfo.Parent == null)
            {
                return false;
            }
            string attributes = dirInfo.Attributes.ToString();
            if (attributes.IndexOf("Hidden") > -1 && attributes.IndexOf("System") > -1)
            {
                return true;
            }
            return false;
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (treeView1.SelectedNode != null)
            {
                try
                {
                    
                    Document doc = (Document)treeView1.SelectedNode.Tag;
                    this.listView1.BeginUpdate();
                    listView1.Items.Clear();
                    if (doc.dir != null)
                    {
                        foreach (FileInfo file in doc.dir.GetFiles())
                        {
                            ListViewItem li = new ListViewItem();
                            li.SubItems[0].Text = file.Name;

                            //获取文件后缀
                            string ext = file.Extension;
                            try
                            {
                                string desc = (string)Registry.ClassesRoot.OpenSubKey(ext).GetValue(null);
                                string typeinfo = (string)Registry.ClassesRoot.OpenSubKey(desc).GetValue(null);
                                if (typeinfo == null)
                                    typeinfo = "";
                                li.SubItems.Add(typeinfo);
                            }
                            catch (Exception) { }
                            listView1.Items.Add(li);
                        }
                    }
                    this.listView1.EndUpdate();

                    this.listView2.BeginUpdate();
                    listView2.Items.Clear();
                    {
                        ListViewItem li = new ListViewItem();
                        li.SubItems[0].Text = "目录数";
                        li.SubItems.Add(doc.currentFolderCount.ToString());
                        listView2.Items.Add(li);
                    }

                    {
                        ListViewItem li = new ListViewItem();
                        li.SubItems[0].Text = "文件数";
                        li.SubItems.Add(doc.currentFileCount.ToString());
                        listView2.Items.Add(li);
                    }

                    foreach (KeyValuePair<string, int> kvp in doc.currentTypes)
                    {
                        ListViewItem li = new ListViewItem();
                        li.SubItems[0].Text = kvp.Key;
                        li.SubItems.Add(kvp.Value.ToString());
                        listView2.Items.Add(li);
                    }

                    this.listView2.EndUpdate();

                    this.listView3.BeginUpdate();
                    listView3.Items.Clear();
                    {
                        ListViewItem li = new ListViewItem();
                        li.SubItems[0].Text = "目录数";
                        li.SubItems.Add(doc.totalFolderCount.ToString());
                        listView3.Items.Add(li);
                    }

                    {
                        ListViewItem li = new ListViewItem();
                        li.SubItems[0].Text = "文件数";
                        li.SubItems.Add(doc.totalFileCount.ToString());
                        listView3.Items.Add(li);
                    }

                    foreach (KeyValuePair<string, int> kvp in doc.totalTypes)
                    {
                        ListViewItem li = new ListViewItem();
                        li.SubItems[0].Text = kvp.Key;
                        li.SubItems.Add(kvp.Value.ToString());
                        listView3.Items.Add(li);
                    }
                    this.listView3.EndUpdate();
                }
                catch (Exception) { }
            }
        }

        public Dictionary<string, int> MergeDictionary(Dictionary<string, int> first, Dictionary<string, int> second)
         {
             foreach (var item in second)
             {
                 if (!first.ContainsKey(item.Key))
                     first.Add(item.Key, item.Value);
                 else
                     first[item.Key] += item.Value;
             }
             return first;
         }


        private void Task_Load(object sender, EventArgs e)
        {
            
        }

        private void treeView1_DoubleClick(object sender, EventArgs e)
        {
            if (((Document)treeView1.SelectedNode.Tag).dir != null)
            {
                System.Diagnostics.Process.Start(((Document)treeView1.SelectedNode.Tag).dir.FullName);
            }
        }

        private void listView1_DoubleClick(object sender, EventArgs e)
        {
            string s = ((Document)treeView1.SelectedNode.Tag).dir.FullName + "\\" + listView1.SelectedItems[0].Text;
            System.Diagnostics.Process.Start(s);
        }
    }
}
